package com.auxgroup.smarthome.business.service;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.PutObjectResult;
import com.auxgroup.bridge.business.inner.vo.AppIndexPageVo;
import com.auxgroup.smarthome.appconst.BusinessConstant;
import com.auxgroup.smarthome.business.service.inner.AppIndexPageInnerService;
import com.auxgroup.smarthome.business.vo.UploadIndexPageVo;
import com.auxgroup.smarthome.filter.PermissionSecurityUserService;
import com.auxgroup.smarthome.qcloud.bean.AlicloudConf;
import com.auxgroup.smarthome.syscode.Syscode;
import com.auxgroup.smarthome.utils.common.LOG;
import com.auxgroup.smarthome.web.ApiResponse;
import com.auxgroup.smarthome.zip.ZipUtil;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

/**
 * @Author: laiqiuhua.
 * @Date: 2017/9/8 18:31.
 */
@Service
public class AppIndexPageService {
    @Autowired
    private AppIndexPageInnerService appIndexPageInnerService;
    @Autowired
    private AlicloudConf alicloudConf;
    @Autowired
    private PermissionSecurityUserService permissionSecurityUserService;

    /**
     * 上传首页文件和预览html到阿里云存储
     * @param file
     * @return
     */
    public ApiResponse<UploadIndexPageVo> uploadIndexPageFile(File file) {
//        File destFile = new File(SystemUtils.getJavaIoTmpDir(), "aux_tmp");
        File destFile = new File("/tmp/auxUpload");
        ApiResponse<Pair<String, String>> apiResponse = parseZip(file, destFile.getAbsolutePath()+File.separator);
        if (apiResponse.getCode() != 200) {
            return (ApiResponse) apiResponse;
        }
        try {
            FileUtils.forceDelete(destFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Pair<String, String> pair = apiResponse.getData();
        return ApiResponse.ok(new UploadIndexPageVo(pair.getLeft(), pair.getRight()));
    }


    /**
     * 发布app首页管理
     * @param indexPageId
     * @return
     */
    public ApiResponse publishAppIndexPage(String indexPageId) {
        ApiResponse result = appIndexPageInnerService.publish(indexPageId, permissionSecurityUserService.getSubjectFromAccessToken());
        return result;
    }

    /**
     * 发布首页版本
     * @param indexPageId
     * @return
     */
    public ApiResponse<AppIndexPageVo> releaseAppIndexPage(String indexPageId) {
        return null;
    }

    /**
     * 获取app首页历史记录，最新5条按时间排序
     * @return
     */
    public ApiResponse getIndexPageHistory() {
        return ApiResponse.ok("暂未实现");
    }

    /**
     * 获取当前app首页版本
     * @return
     */
    public ApiResponse getCurrentIndexPage() {
        return ApiResponse.ok("暂未实现");
    }


    /**
     * 解析zip包生成预览文件上传到对象存储，以及储存源zip包
     * @param zipFile
     * @param destSrc
     *  result:
     *    Left:zip路径， Right:html文件路径
     */
    private ApiResponse<Pair<String, String>> parseZip(File zipFile, String destSrc) {
        try {
            Pair<Boolean, String> zipUpload = uploadFile(zipFile);
            Pair<Boolean, String> PreHtmlFile = null;
            boolean isSuccess = zipUpload.getLeft();
            if(!isSuccess) {
                LOG.warn(this, "上传app首页文件失败");
                return ApiResponse.prompt(Syscode.FAIL.getCode()+"", "文件上传失败");
            }
            ZipUtil.unZipFiles(zipFile, destSrc);
            File list = new File(destSrc);
            File[] htmlFilelist = list.listFiles((dir, name) -> name.endsWith(".html"));
            if(htmlFilelist.length <= 0) {
                return ApiResponse.prompt(Syscode.FAIL.getCode()+"", "html主文件不存在");
            }
            if(htmlFilelist.length > 1) {
                return ApiResponse.prompt(Syscode.FAIL.getCode()+"", "存在多个html主文件");
            }
            Document document = Jsoup.parse(htmlFilelist[0], StandardCharsets.UTF_8.name());
            Element baseTag = new Element("base").attr("href", alicloudConf.getReturnUrlPrefix());
            document.head().appendChild(baseTag);
            // 上传预览文件失败了
            boolean preHtmlFlag= true;
            File[] entireFile = list.listFiles();

            for(File file: entireFile) {
                if(!file.isDirectory()) {
                    Pair<Boolean, String> tmpFile = uploadFile(file);
                    preHtmlFlag = tmpFile.getLeft();
                    if(file.getName().endsWith(".html")) {
                        PreHtmlFile = tmpFile;
                    }
                }
            }
            if(!preHtmlFlag) {
                LOG.warn(this, "生成预览文件失败");
                return ApiResponse.prompt(Syscode.FAIL.getCode()+"", "生成预览文件失败");
            }
//            System.out.println(document);
//            System.out.println(Arrays.toString(htmlFilelist));
            return ApiResponse.ok(Pair.of(zipUpload.getRight(), PreHtmlFile.getRight()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ApiResponse.prompt(Syscode.FAIL);
    }

    /**
     * 上传文件到阿里云存储
     * @param file
     * @return
     */
    private Pair<Boolean, String> uploadFile(File file) {
        OSSClient ossClient = new OSSClient(alicloudConf.getEndpoint(), alicloudConf.getAccessKeyId(), alicloudConf.getAccessKeySecret());
        String finalName = file.getName();
        LocalDate today = LocalDate.now();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMdd");
        String uploadPath = today.format(df)+"/"+ BusinessConstant.UPLOAD_OSS_PREFIX_PATH_INDEXPAGE.getValue()+"/";
        //正式操作开始
        PutObjectResult result = ossClient.putObject(alicloudConf.getBucketName(), uploadPath+finalName, file);
        //这里可以添加回调函数
        // result.setCallbackResponseBody();
        //正式操作结束，关闭释放资源
        ossClient.shutdown();
        StringBuffer stringBuffer=new StringBuffer(alicloudConf.getReturnUrlPrefix());
        stringBuffer.append('/'+uploadPath);
        stringBuffer.append(finalName);
        return Pair.of(true, stringBuffer.toString());
    }
}
